package com.king.juc.syncmode;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;

/**
 * 交替输出
 *
 * @author king
 * @date 2020/11/22 22:18
 */
@Slf4j(topic = "c.AlternateOutput")
public class AlternateOutput {

    static Thread a;
    static Thread b;
    static Thread c;

    public static void main(String[] args) {
//        waitNotify();
//        awaitSignal();
        parkUnpark();

    }

    /**
     * wait() notify() 交替运行案例
     */
    public static void waitNotify(){
        WaitNofity wn = new WaitNofity(1, 5);
        new Thread(() -> {
            wn.print("a", 1, 2);
        }).start();
        new Thread(() -> {
            wn.print("b", 2, 3);
        }).start();
        new Thread(() -> {
            wn.print("c", 3, 1);
        }).start();
    }

    /**
     * ReentrantLock 交替运行案例
     */
    public static void awaitSignal(){
        AwaitSignal awaitSignal = new AwaitSignal(5);
        Condition a = awaitSignal.newCondition();
        Condition b = awaitSignal.newCondition();
        Condition c = awaitSignal.newCondition();
        new Thread(() -> {
            awaitSignal.print("a", a, b);
        }).start();
        new Thread(() -> {
            awaitSignal.print("b", b, c);
        }).start();
        new Thread(() -> {
            awaitSignal.print("c", c, a);
        }).start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        awaitSignal.lock();
        try {
            log.debug("开始...");
            a.signal();
        }finally {
            awaitSignal.unlock();
        }
    }

    /**
     * park() unpark() 交替运行案例
     */
    public static void parkUnpark(){
        ParkUnpark pu = new ParkUnpark(5);

        a = new Thread(() -> {
            pu.print("a", b);
        });
        b = new Thread(() -> {
            pu.print("b", c);
        });
        c = new Thread(() -> {
            pu.print("c", a);
        });
        a.start();
        b.start();
        c.start();

        LockSupport.unpark(a);
    }
}
